<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
		<meta name="apple-mobile-web-app-capable" content="yes">
		<meta name="apple-mobile-web-app-status-bar-style" content="black">
		<link rel="stylesheet" type="text/css" href="../../css/mui.min.css" />
		<script src="../../js/mui.min.js" type="text/javascript" charset="utf-8"></script>
		<style>
			.main_content p {
				font-size: 1em;
				color: black;
				text-indent: 2em;
				padding: 6px;
			}
			.main_content img {
				padding: 8px;
			}
			.mui-content{
				width: 100%;
			}
			.sub_header {
				text-align: center;
				background-color: rgba(0, 188, 0, 0.7);
				height: 36px;
				margin-top: 8px;
				margin-bottom: 8px;
			}
			.sub_header h3 {
				color: white;
				position: relative;
				top: 20%;
				transform: translateY(-50%);
			}
		</style>
	</head>

	<body>
		<header class="mui-bar mui-bar-nav">
			<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
			<h1 class="mui-title">Java 基础</h1>
		</header>
		<div class="mui-content">
			<div class="mui-content-padded" style="margin: 5px;">
				<div class="sub_header">
					<h3>Java数据类型</h3>
				</div>
				<div class="main_content">
					<p><span style="font-family:microsoft yahei">Java语言是静态类型的（statical typed)，也就是说所有变量和表达式的类型再编译时就已经完全确定。由于是statical typed，导致Java语言也是强类型（Strong typed）的。强类型意味着每个变量都具有一种类型，每个表达式具有一种类型，并且每种类型都是严格定义的，类型限制了变量可以hold哪些值，表达式最终产生什么值。同时限制了这些值可以进行的操作类型以及操作的具体方式。所有的赋值操作，无论是显式的还是在方法调用中通过参数传递，都要进行类型兼容性检查。</span></p>

					<h1><a name="t0"></a><span style="color:rgb(255, 0, 0)"><strong><span style="font-family:microsoft yahei; font-size:14px">1. 数据类型：</span></strong></span></h1>

					<p><span style="font-family:microsoft yahei">在java源代码中，每个变量都必须声明一种类型（type）。有两种类型：primitive type和reference type。引用类型引用对象（reference to object），而基本类型直接包含值（directly contain value）。因此，Java数据类型（type）可以分为两大类：基本类型（primitive types）和引用类型（reference types）。primitive types 包括boolean类型以及数值类型（numeric types）。numeric types又分为整型（integer types）和浮点型（floating-point type）。整型有5种：byte short int long char(char本质上是一种特殊的int)。浮点类型有float和double。关系整理一下如下图：</span></p>

					<p><span style="font-family:microsoft yahei"><img alt="" src="http://img.blog.csdn.net/20140531091306906" style="border:none; max-width:100%" /></span></p>

					<p><span style="font-family:microsoft yahei">对象是动态创建的类实例或者动态创建的数组。The value of reference types are references to objects，而引用一般是指内存地址。所有的对象（包括数组）支持Object类中定义的方法。String literals are presented by String object.</span></p>

					<p>&nbsp;</p>

					<p><span style="font-family:microsoft yahei">java有两种类型（type），与之相对应的是两种数据的值（two kinds of data values that can be stored in variable, pass as arguments and returned by methods)，这两只data values是：primitive values，reference values。也许这么理解起来更方便（虽然不严谨），Java变量有两种：primitive variable和reference variable，在变量中，它们分别存储primitive value和reference value。</span></p>

					<p><span style="font-family:microsoft yahei">null是一种特殊的type，但是你不能声明一个变量为null类型，null type的唯一取值就是null。null可以负值给任意的引用类型或者转化成任意的引用类型。在实践中，一般把null当做字面值（literal），这个字面值可是是任意的引用类型。</span></p>

					<h1><a name="t1"></a><span style="color:rgb(255, 0, 0)"><strong><span style="font-family:microsoft yahei; font-size:14px">2. 基本类型：</span></strong></span></h1>

					<p><span style="font-family:microsoft yahei">Java为基本类型提供语言级别的支持，即已经在Java中预定义，用相应的保留关键字表示。基本类型是单个值，而不是复杂的对象，基本类型不是面向对象的，主要出去效率方面的考虑，但是同时也提供基本类型的对象版本，即基本类型的包装器（wrapper）。可以直接使用这些基本类型，也可以使用基本类型构造数组或者其他自定义类型。基本类型具有明确的取值范围和数学行为。</span></p>

					<h2><a name="t2"></a><strong><span style="font-family:microsoft yahei; font-size:14px">2.1 整型</span></strong></h2>

					<p><span style="font-family:microsoft yahei">整型有byte short int long char，分别用8、16、32、64、16bits表示。有些地方可能不会把char列入整型范畴，但本质上char类型是int的一个子集。整型的宽度不应该被看成整数所占用的内存空间大小，而应当理解成定义为整型的变量或者表达式的行为。JVM可以自由使用它们希望的、任何大小的内存空间，只要类型的行为符合规范。byte short int long都是有符号的，用2的补码（two&lsquo;s-complement）表示。而char用16位表示，它是无符号的，表示的是UTF-16编码集。</span></p>

					<h3><a name="t3"></a><span style="font-family:microsoft yahei; font-size:14px">2.1.1 byte</span></h3>

					<p><span style="font-family:microsoft yahei">byte由1个字节8位表示，是最小的整数类型。主要用于节省内存空间关键。当操作来自网络、文件或者其他IO的数据流时，byte类型特别有用。取值范围为:[-128, 127]. byte的默认值为(byte)0,如果我们试图将取值范围外的值赋给byte类型变量，则会出现编译错误，例如 byte b = 128；这个语句是无法通过编译的。一个有趣的问题，如果我们有个方法： public void test(byte b)。试图这么调用这个方法是错误的: test(0); 编译器会报错，类型不兼容！！！我们记得byte b =0；这是完全没有问题的，为什么在这里就出错啦？</span></p>

					<p><span style="font-family:microsoft yahei">这里涉及到一个叫字面值（literal）的问题，字面值就是表面上的值，例如整型字面值在源代码中就是诸如 5 ， 0， -200这样的。如果整型子面子后面加上L或者l，则这个字面值就是long类型，比如：1000L代表一个long类型的值。如果不加L或者l，则为int类型。基本类型当中的byte short int long都可以通过不加L的整型字面值（我们就称作int字面值吧）来创建，例如 byte b = 100； short s = 5；对于long类型，如果大小超出int所能表示的范围（32 bits），则必须使用L结尾来表示。整型字面值可以有不同的表示方式：16进制【0X or 0x】、10进制【nothing】、八进制【0】2进制【0B or 0b】等，二进制字面值是JDK 7以后才有的功能。在赋值操作中，int字面值可以赋给byte short int long，Java语言会自动处理好这个过程。如果方法调用时不一样，调用test（0）的时候，它能匹配的方法是test（int），当然不能匹配test（byte）方法，至于为什么Java没有像支持赋值操作那样支持方法调用，不得而知。注意区别包装器与原始类型的自动转换（anto-boxing，auto-unboxing）。byte d = &#39;A&#39;；也是合法的，字符字面值可以自动转换成16位的整数。</span></p>

					<p><span style="font-family:microsoft yahei">更多关于字面值的介绍，参考oracle文档（<a href="#" style="color: rgb(255, 153, 0);>123</a>）。</span></p>

					<h3><a name="t4"></a><span style="font-family:microsoft yahei; font-size:14px">2.1.2 short</span></h3>

					<p><span style="font-family:microsoft yahei">用16为表示，取值范围为：[- 2^15, 2^15 - 1]。short可能是最不常用的类型了。可以通过整型字面值或者字符字面值赋值，前提是不超出范围（16 bit）。short类型参与运算的时候，一样被提升为int或者更高的类型。（顺序为 byte short int long float double).</span></p>

					<h3><a name="t5"></a><span style="font-family:microsoft yahei; font-size:14px">2.1.3 int</span></h3>

					<p><span style="font-family:microsoft yahei">32 bits, [- 2^31, 2^31 - 1].有符号的二进制补码表示的整数。常用语控制循环，注意byte 和 short在运算中会被提升为int类型或更高。Java 8以后，可以使用int类型表示无符号32位整数[ 0, 2^31 - 1]。</span></p>

					<h3><a name="t6"></a><span style="font-family:microsoft yahei; font-size:14px">2.1.4 long</span></h3>

					<p><span style="font-family:microsoft yahei">64 bits， [- 2^63, 2^63 - 1,默认值为0L].当需要计算非常大的数时，如果int不足以容纳大小，可以使用long类型。如果long也不够，可以使用BigInteger类。</span></p>

					<h3><a name="t7"></a><span style="font-family:microsoft yahei; font-size:14px">2.1.5 char</span></h3>

					<p><span style="font-family:microsoft yahei">16 bits, [0, 65535], [0, 2^16 -1],从&#39;\u0000&#39;到&#39;\uffff&#39;。无符号，默认值为&#39;\u0000&#39;。Java使用Unicode字符集表示字符，Unicode是完全国际化的字符集，可以表示全部人类语言中的字符。Unicode需要16位宽，所以Java中的char类型也使用16 bit表示。 赋值可能是这样的：</span></p>

					<p><span style="font-family:microsoft yahei">char ch1 = 88;</span></p>

					<p><span style="font-family:microsoft yahei">char ch2 = &#39;A&#39;;</span></p>

					<p><span style="font-family:microsoft yahei">ASCII字符集占用了Unicode的前127个值。之所以把char归入整型，是因为Java为char提供算术运算支持，例如可以ch2++;之后ch2就变成Y。当char进行加减乘除运算的时候，也被转换成int类型，必须显式转化回来。</span></p>

					<h2><a name="t8"></a><strong><span style="font-family:microsoft yahei; font-size:14px">2.2 浮点类型</span></strong></h2>

					<p><span style="font-family:microsoft yahei">包含单精度的float和双精度的double，分别用32、64bits表示，遵循IEEE 754规范。</span></p>

					<h3><a name="t9"></a><span style="font-family:microsoft yahei; font-size:14px">2.2.1 float</span></h3>

					<p><span style="font-family:microsoft yahei">使用32 bit表示，对应单精度浮点数，运行速度相比double更快，占内存更小，但是当数值非常大或者非常小的时候会变得不精确。</span></p>

					<h3><a name="t10"></a><span style="font-family:microsoft yahei; font-size:14px">2.2.2 double</span></h3>

					<p><span style="font-family:microsoft yahei">64为表示，将浮点子面子赋给某个变量时，如果不显示在字面值后面加f或者F，则默认为double类型。java.lang.Math中的函数都采用double类型。</span></p>

					<p><span style="font-family:microsoft yahei">如果double和float都无法达到想要的精度，可以使用BigDecimal类。</span></p>

					<h2><a name="t11"></a><strong><span style="font-family:microsoft yahei; font-size:14px">2.3 boolean类型</span></strong></h2>

					<p><span style="font-family:microsoft yahei">boolean类型只有两个值true和false，默认为false。boolean与是否为0没有任何关系，但是可以根据想要的逻辑进行转换。许多地方都需要用到boolean类型。</span></p>

					<h1><a name="t12"></a><span style="color:rgb(255, 0, 0)"><strong><span style="font-family:microsoft yahei; font-size:14px">3. 字面值</span></strong></span></h1>

					<p><span style="font-family:microsoft yahei">在Java源代码中，字面值用于表示固定的值（fixed value）。数值型的字面值是最常见的，字符串字面值可以算是一种，当然也可以把特殊的null当做字面值。字面值大体上可以分为整型字面值、浮点字面值、字符和字符串字面值、特殊字面值。</span></p>

					<h2><a name="t13"></a><strong><span style="font-family:microsoft yahei; font-size:14px">3.1. 整型字面值</span></strong></h2>

					<p><span style="font-family:microsoft yahei">从形式上看是整数的字面值归类为整型字面值。例如： 10, 100000L, &#39;B&#39;、0XFF这些都可以称为字面值。整型字面值可以用十进制、16、8、2进制来表示。十进制很简单，2、8、16进制的表示分别在最前面加上0B（0b）、0、0X（0x）即可，当然基数不能超出进制的范围，比如09是不合法的，八进制的基数只能到7。一般情况下，字面值创建的是int类型，但是int字面值可以赋值给byte short char long int，只要字面值在目标范围以内，Java会自动完成转换，如果试图将超出范围的字面值赋给某一类型（比如把128赋给byte类型），编译通不过。而如果想创建一个int类型无法表示的long类型，则需要在字面值最后面加上L或者l。通常建议使用容易区分的L。所以整型字面值包括int字面值和long字面值两种。</span></p>

					<h2><a name="t14"></a><strong><span style="font-family:microsoft yahei; font-size:14px">3.2. 浮点字面值</span></strong></h2>

					<p><span style="font-family:microsoft yahei">浮点字面值简单的理解可以理解为小数。分为float字面值和double字面值，如果在小数后面加上F或者f，则表示这是个float字面值，如11.8F。如果小数后面不加F（f），如10.4。或者小数后面加上D（d），则表示这是个double字面值。</span></p>

					<h2><a name="t15"></a><span style="font-family:microsoft yahei; font-size:14px"><strong>3.3 字符及字符串字面值</strong></span></h2>

					<p><span style="font-family:microsoft yahei">Java中字符字面值用单引号括起来，如&lsquo;@&rsquo;&lsquo;1&rsquo;。所有的UTF-16字符集都包含在字符字面值中。不能直接输入的字符，可以使用转义字符，如&lsquo;\n&rsquo;为换行字符。也可以使用八进制或者十六进制表示字符，八进制使用反斜杠加3位数字表示，例如&#39;\141&#39;表示字母a。十六进制使用\u加上4为十六进制的数表示，如&#39;\u0061&#39;表示字符a。也就是说，通过使用转义字符，可以表示键盘上的有的或者没有的所有字符。常见的转义字符序列有：</span></p>

					<p><span style="font-family:microsoft yahei">\ddd(八进制) 、 \uxxxx(十六进制Unicode字符)、\&#39;（单引号）、\&quot;（双引号）、\\ （反斜杠）\r（回车符） \n（换行符） \f（换页符） \t（制表符） \b（回格符）</span></p>

					<p><span style="font-family:microsoft yahei">字符串字面值则使用双引号，字符串字面值中同样可以包含字符字面值中的转义字符序列。字符串必须位于同一行或者使用+运算符，因为java没有续行转义序列。</span></p>

					<h2><a name="t16"></a><strong><span style="font-family:microsoft yahei; font-size:14px">3.4 特殊字面值</span></strong></h2>

					<p><span style="font-family:microsoft yahei">null是一种特殊的类型（type），可以将它赋给任何引用类型变量，表示这个变量不引用任何东西。如果一个引用类型变量为null，表示这个变量不可用。</span></p>

					<p><span style="font-family:microsoft yahei">还有一种特殊的class literal，用type name加上.class表示,例如String.class。首先，String是类Class（java.lang.Class)的一个实例（对象），而&quot;This is a string&quot;是类String的一个对象。然后，class literal用于表示类Class的一个对象，比如String.class用于表示类Class的对象String。简单地说，类子面子（class literal）就是诸如String.class 、Integer.class这样的字面值，它所表示的就是累String、类Integer。如果输出Integer.class，你会得到class java.lang.Integer。List.class的输出为interface java.util.List。总之，class literal用于表示类型本身！</span></p>

					<h2><a name="t17"></a><span style="font-family:microsoft yahei; font-size:14px"><strong>3.5 在数值型字面值中使用下划线</strong>。</span></h2>

					<p><span style="font-family:microsoft yahei">JDK7开始，可以在数值型字面值（包括整型字面值和浮点字面值）插入一个或者多个下划线。但是下划线只能用于分隔数字，不能分隔字符与字符，也不能分隔字符与数字。例如 int x = 123_456_789.在编译的时候，下划线会自动去掉。可以连续使用下划线，比如float f = 1.22___33__44.二进制或者十六进制的字面值也可以使用下划线，记住一点，下划线只能用于数字与数字之间，初次以外都是非法的。例如1._23是非法的，_123、11000_L都是非法的。</span></p>

					<h1><a name="t18"></a><strong><span style="color:rgb(255, 0, 0)"><span style="font-family:microsoft yahei; font-size:14px">4. 基本类型之间的转换</span></span></strong></h1>

					<p><span style="font-family:microsoft yahei">我们看到，将一种类型的值赋给另一种类型是很常见的。在Java中，boolean类型与所有其他7种类型都不能进行转换，这一点很明确。对于其他7中数值类型，它们之间都可以进行转换，但是可能会存在精度损失或者其他一些变化。转换分为自动转换和强制转换。对于自动转换（隐式），无需任何操作，而强制类型转换需要显式转换，即使用转换操作符（type）。首先将7种类型按下面顺序排列一下：</span></p>

					<p><span style="font-family:microsoft yahei">byte &lt;（short=char）&lt; int &lt; long &lt; float &lt; double</span></p>

					<p><span style="font-family:microsoft yahei">如果从小转换到大，可以自动完成，而从大到小，必须强制转换。short和char两种相同类型也必须强制转换。</span></p>

					<h2><a name="t19"></a><strong><span style="font-family:microsoft yahei; font-size:14px">4.1 自动转换</span></strong></h2>

					<p><span style="font-family:microsoft yahei">自动转换时发生扩宽（widening conversion）。因为较大的类型（如int）要保存较小的类型（如byte），内存总是足够的，不需要强制转换。如果将字面值保存到byte、short、char、long的时候，也会自动进行类型转换。注意区别，此时从int（没有带L的整型字面值为int）到byte/short/char也是自动完成的，虽然它们都比int小。在自动类型转化中，除了以下几种情况可能会导致精度损失以外，其他的转换都不能出现精度损失。</span></p>

					<p><span style="font-family:microsoft yahei">》int--&gt; float</span></p>

					<p><span style="font-family:microsoft yahei">》long--&gt; float</span></p>

					<p><span style="font-family:microsoft yahei">》long--&gt; double</span></p>

					<p><span style="font-family:microsoft yahei">》float --&gt;double without strictfp</span></p>

					<p><span style="font-family:microsoft yahei">除了可能的精度损失外，自动转换不会出现任何运行时（run-time）异常。</span></p>

					<h2><a name="t20"></a><strong><span style="font-family:microsoft yahei; font-size:14px">4.2 强制类型转换</span></strong></h2>

					<p><span style="font-family:microsoft yahei">如果要把大的转成小的，或者在short与char之间进行转换，就必须强制转换，也被称作缩小转换（narrowing conversion）,因为必须显式地使数值更小以适应目标类型。强制转换采用转换操作符（）。严格地说，将byte转为char不属于narrowing conversion），因为从byte到char的过程其实是byte--&gt;int--&gt;char，所以widening和narrowing都有。强制转换除了可能的精度损失外，还可能使模（overall magnitude）发生变化。强制转换格式如下：</span></p>

					<p><span style="font-family:microsoft yahei">（target-type） value</span></p>

					<p><span style="font-family:microsoft yahei">如果整数的值超出了byte所能表示的范围，结果将对byte类型的范围取余数。例如a=256超出了byte的[-128,127]的范围，所以将257除以byte的范围（256）取余数得到b=1；需要注意的是，当a=200时，此时除了256取余数应该为-56，而不是200.</span></p>

					<p><span style="font-family:microsoft yahei">将浮点类型赋给整数类型的时候，会发生截尾（truncation）。也就是把小数的部分去掉，只留下整数部分。此时如果整数超出目标类型范围，一样将对目标类型的范围取余数。</span></p>

					<p><span style="font-family:microsoft yahei">7中基本类型转换总结如下图：</span></p>

					<p><span style="font-family:microsoft yahei"><img alt="" src="http://img.blog.csdn.net/20140531150520890" style="border:none; max-width:100%" /></span></p>

					<h2><a name="t21"></a><span style="font-family:microsoft yahei; font-size:14px"><strong>4.3 赋值及表达式中的类型转换：</strong></span></h2>

					<h3><a name="t22"></a><span style="font-family:microsoft yahei; font-size:14px">4.3.1 字面值赋值</span></h3>

					<p><span style="font-family:microsoft yahei">在使用字面值对整数赋值的过程中，可以将int literal赋值给byte short char int，只要不超出范围。这个过程中的类型转换时自动完成的，但是如果你试图将long literal赋给byte，即使没有超出范围，也必须进行强制类型转换。例如 byte b = 10L；是错的，要进行强制转换。</span></p>

					<h3><a name="t23"></a><span style="font-family:microsoft yahei; font-size:14px">4.3.2 表达式中的自动类型提升</span></h3>

					<p><span style="font-family:microsoft yahei">除了赋值以外，表达式计算过程中也可能发生一些类型转换。在表达式中，类型提升规则如下：</span></p>

					<p><span style="font-family:microsoft yahei">》所有byte/short/char都被提升为int。</span></p>

					<p><span style="font-family:microsoft yahei">》如果有一个操作数为long，整个表达式提升为long。float和double情况也一样。</span></p>

				</div>
			</div>
		</div>

	</body>

</html>